package org.dh2580.netty.demo.netty.protocol.privately;

import java.net.InetSocketAddress;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class LogingAuthRespHandler extends ChannelInboundHandlerAdapter {

    private Map<String, Boolean> nodeCheck = new ConcurrentHashMap<>();

    private Set<String> whiteClientIp = new HashSet();

    {
        whiteClientIp.add("127.0.0.1");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        NettyMessage message = (NettyMessage) msg;

        if (message.getHeader() != null && message.getHeader().getType() == NettyMessageType.LOGIN_REQ.getValue()) {

            NettyMessage resp = null;

            String clientAddress = ctx.channel().remoteAddress().toString();

            if (nodeCheck.containsKey(clientAddress)) {
                resp = buildResponse((byte) -1);
            } else {
                InetSocketAddress addres = (InetSocketAddress) ctx.channel().remoteAddress();

                String ip = addres.getAddress().getHostAddress();

                resp = whiteClientIp.contains(ip) ? buildResponse((byte) 0) : buildResponse((byte) -1);

                if (whiteClientIp.contains(ip)) {
                    nodeCheck.put(clientAddress, true);
                }
            }

            ctx.writeAndFlush(resp);

        } else {
            ctx.fireChannelRead(msg);
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();

        nodeCheck.remove(ctx.channel().remoteAddress().toString());

        ctx.close();

        ctx.fireExceptionCaught(cause);
    }

    private NettyMessage buildResponse(byte result) {
        NettyMessage message = new NettyMessage();

        NettyHeader header = new NettyHeader();
        header.setType(NettyMessageType.LOGIN_RESP.getValue());

        message.setHeader(header);
        message.setBody(result);

        return message;
    }
}
